home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Over 1,000 Windows 95 Programs
/
Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso
/
1249
/
mat_util.t
< prev
next >
Wrap
Text File
|
1997-04-18
|
5KB
|
302 lines
%
% "mat_util.t" contains matrix utility functions for use
% in other programs.
%
% To use, add file to list in "*.prt" file
%
% Dimension 'DIM' should be declared as a global constant
% in the main program file.
%
% Sample program for the T Interpreter by:
%
% Stephen R. Schmitt
% 962 Depot Road
% Boxborough, MA 01719
%
type rmatrix : array[DIM,DIM] of real
type rvector : array[DIM] of real
type ivector : array[DIM] of int
%
% print a matrix
%
procedure print_mat( var m : rmatrix )
var i, j : int
for i := 0...DIM-1 do
for j := 0...DIM-1 do
put m[i,j]:15:6...
end for
put ""
end for
end procedure
%
% return the absolute value of a real number
%
function rabs( x : real ) : real
if x < 0.0 then
x := -x
end if
return x
end function
%
% invert a square matrix using Gauss-Jordan method
%
% note: pivoting will sometimes fail; set pivot to false to disable
%
function invert( var a, b : rmatrix, pivot : boolean ) : real
var w : array[DIM,2*DIM] of real
var p : array[DIM] of int
var s, t, det : real
var i, j, k : int
label invert_exit :
% setup workspace : [A|I]
for i := 0...DIM-1 do
for j := 0...DIM-1 do
w[i,j] := a[i,j]
w[i,j+DIM] := 0.0
end for
w[i,i+DIM] := 1.0
end for
det := 0.0
% convert to upper triangular form
for k := 0...DIM-2 do
j := k
t := 0.0
if pivot then % find pivot row for column k
for i := k...DIM-1 do
s := rabs( w[i,k] )
if s > t then
t := s
j := i
end if
end for
end if
p[k] := j % save pivot row number
if j ~= k then % swap rows
for i := k...2*DIM-1 do
t := w[j,i]
w[j,i] := w[k,i]
w[k,i] := t
end for
end if
end for
p[DIM-1] := DIM - 1
% zeroize elements below each diagonal element
for k := 0...DIM-2 do
if w[k,k] = 0.0 then
goto invert_exit
end if
for i := k+1...DIM-1 do
t := w[i,k] / w[k,k]
for j := k...2*DIM-1 do
w[i,j] := w[i,j] - t * w[k,j]
end for
end for
end for
% compute determinant
det := 1.0
i := 1
for k := 0...DIM-1 do
if p[k] ~= k then
i := -i
end if
det := det * w[k,k]
end for
det := i * det
% make diagonal elements = 1
for k := 0...DIM-1 do
t := w[k,k]
for j := k...2*DIM-1 do
w[k,j] := w[k,j] / t
end for
end for
% zeroize elements above each diagonal element
for decreasing k := DIM-1...1 do
for decreasing i := k-1...0 do
t := w[i,k]
for j := k...2*DIM-1 do
w[i,j] := w[i,j] - t * w[k,j]
end for
end for
end for
% output results
for i := 0...DIM-1 do
for j := 0...DIM-1 do
b[i,j] := w[i,j+DIM]
end for
end for
invert_exit :
return det
end function
%
% multiply two square matrices
%
procedure mul_mat_mat( var a, b, c : rmatrix )
var i, j, k : int
var s : real
for i := 0...DIM-1 do
for j := 0...DIM-1 do
s := 0.0
for k := 0...DIM-1 do
s := s + a[i,k] * b[k,j]
end for
c[i,j] := s
end for
end for
end procedure
%
% multiply a square matrix by a vector
%
procedure mul_mat_vec( var a : rmatrix, var x, y : rvector )
var i, j : int
var s : real
for i := 0...DIM-1 do
s := 0.0
for j := 0...DIM-1 do
s := s + a[i,j] * x[j]
end for
y[i] := s
end for
end procedure
%
% decompose a square matrix into symmetric and skew-symmetric parts
%
procedure sym_mat( var a, m, s : rmatrix )
var i, j : int
for i := 0...DIM-1 do
for j := 0...DIM-1 do
m[i,j] := ( a[i,j] + a[j,i] ) / 2
end for
end for
for i := 0...DIM-1 do
for j := 0...DIM-1 do
s[i,j] := ( a[i,j] - a[j,i] ) / 2
end for
end for
end procedure